Fetch 與 Promise (一):初探 Fetch


Posted by s103071049 on 2021-07-10

若要在前端網站發 AJAX Request,有兩種方法

法一、XML HTTP Request,簡稱 xhr
法二、Fetch

要串 api 練習,但沒有 api 怎麼辦 ?
透過mocky,可以自己創造出一個 response,然後就可以自己抓 response 回來。

Fetch 怎麼用 GET

fetch(網址) === 發 request

  <script>
    fetch('https://run.mocky.io/v3/82ec874a-086c-48ef-8195-37686b61f372')
  </script>

接著想看,call 這個 funct 會回傳甚麼東西

  <script>
    const result = fetch('https://run.mocky.io/v3/82ec874a-086c-48ef-8195-37686b61f372')
    console.log(result)
  </script>

回傳後出現了 promise。promise 是一個物件的類型,比如說使用 jQuery 時,$(.button) 這個 function 回傳的會是一個 jQuery 的物件,Promise 也是一個獨特的物件,就跟正規表達是 RegExp 也是一個獨特的物件一樣。fetch 會回傳 Promise 這個獨特的物件,但其他的 functon 也可能會回傳 Promise

要拿到 Promise 的結果,要使用 .then(),括號內要接的是一個 callback function。

  <script>
    function printResult(a) {
      console.log(a)
    }
    const result = fetch('https://run.mocky.io/v3/82ec874a-086c-48ef-8195-37686b61f372')
    result.then(printResult)
  </script>

a 會是一個 response,我們成功拿到回傳的結果。

可以簡化上述 code

    fetch('https://run.mocky.io/v3/82ec874a-086c-48ef-8195-37686b61f372')
      .then((a) => {
        console.log(a)
      })

取 response 的 status

  <script>
    const api500 = 'https://run.mocky.io/v3/c5989253-8bcf-4f6a-970a-c393cdd5090e'
    const api200 = 'https://run.mocky.io/v3/82ec874a-086c-48ef-8195-37686b61f372'
    function printResult(a) {
      console.log(a)
    }
    fetch(api500)
      .then((response) => {
        console.log(response.status)
      })
  </script>

絕大多數時候,我們想要的是 response 的內容,直接 console.log(response.body) 會出現 => ReadableStream,會不知道怎麼讀他。所以 response 上面提供了幾個方法

法一、response.text() => 回傳的會是 promise

    const api500 = 'https://run.mocky.io/v3/c5989253-8bcf-4f6a-970a-c393cdd5090e'
    const api200 = 'https://run.mocky.io/v3/82ec874a-086c-48ef-8195-37686b61f372'
    function printResult(a) {
      console.log(a)
    }
    fetch(api500)
      .then((response) => {
        response.text().then(text => {
          console.log(text)
        })
      })

法二、response.json() => 回傳的會是 promise
與法一的不同在於,會將 response 的內容用 json.parse 變成一個 json 的字串。
他相當於是法一做了這件事

    .then((response) => {
        response.text().then(text => {
          console.log(JSON.parse(text))
        })
      })

fetch() 回傳的會是 promise
response.text()、response.json() 回傳的也會是 promise
response.json().then() 回傳的還是 promise
promise 要拿資料必須透過 .then() 括號接 cb function 就可以拿到資料

.then() 無窮無盡 Chaining

.then 裡面又 .then 很難閱讀,所以可以利用 promise 的神奇特性
.then return 的東西會是下一個 .then 裡面的值。如果 return 是 undefined,.then 裡面的值就是 undefined。

    fetch(api200)
    .then((response) => {
        console.log(response.status)
        response.text().then(text => {
          console.log((text))
          return 123
        }).then((abc) => {
          console.log('abc', abc) //abc 123
        })
      })

不 return 任何東西,預設就是 undefined,所以 abc 就是 undefined

    fetch(api200)
    .then((response) => {
        console.log(response.status)
        response.text().then(text => {
          console.log((text))
        }).then((abc) => {
          console.log('abc', abc) //abc undefined
        })
      })

為甚麼 .then() 完還可以再 .then() ?
因為 .then() 也是一個 function,所以 .then() 這個 function 回傳的還是一個 promise,所以可以再繼續接續下去。

這跟這個很像,當我們呼叫 css 這個 function,這個 function 的回傳值是另外一個 jQuery 的物件,所以她又可以再 .hide(),.hide() 回傳的也是一個 jQuery 的物件,所以可以再 .show(),因為一直 return 自己,才可以做到這樣的事情,我們叫他 chaining。

$('.button').css(...).hide().show()

return 的東西如果是 promise,那我再下一個 .then 拿到的值,就會是解析完的值

這個 text 是 response.text() 這個 promise 的回傳值。

response.text().then(text =>)

我拿到的 abc 就會是 response.text() 的結果

    fetch(api200)
      .then((response) => {
        return response.text()
      }).then(abc => {
        console.log(abc)
      })

可以利用這個特性,縮排較少,更好閱讀拿到資料。cb 大時代極力避免很多層、縮排很多,因為會很難追蹤程式碼。

重點回顧

  1. return 的是值,他會自動帶到下面去
  2. return 的是 promise,會將 promise 解析完後,用 .then 的方式拿出來的值,帶到下面去。(可以利用這樣的方式,拿到 json 格式的資料)

#Fetch 與 Promise







Related Posts

簡單的 JS 陣列 method 整理

簡單的 JS 陣列 method 整理

Robot Framework之第一個helloworld練習題

Robot Framework之第一個helloworld練習題

01. Install Python, Flask and virtual environment

01. Install Python, Flask and virtual environment


Comments